﻿using BLToolkit.Data;
using BLToolkit.Data.Linq;
using CommonHelper;
using CommonLibrary;
using CommonLibrary.Models;
using CommonSite.Areas.API.Models;
using CommonSite.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Web;
using System.Web.Mvc;

namespace CommonSite.Areas.API.Controllers
{
    public class UserController : BaseAPIController
    {
        public ActionResult Query()
        {
            using (CommonDatabase db = new CommonDatabase())
            {
                var query = (from p in db.sys_User
                             where p.State == 1
                             select new User
                             {
                                 Id = CryptHelper.Encrypt(p.Id),
                                 LoginName = p.LoginName,
                                 UserName = p.sys_UserInfo.UserName,
                                 Sex = p.sys_UserInfo.Sex,
                                 WorkEmail = p.sys_UserInfo.WorkEmail,
                                 Mobile = p.sys_UserInfo.Mobile,
                                 Tel = p.sys_UserInfo.Tel
                             }).ToList();

                return Success(new
                {
                    Total = query.Count,
                    Rows = query
                });
            }
        }

        public ActionResult GetUsers()
        {
            using (CommonDatabase db = new CommonDatabase())
            {
                var query = (from p in db.sys_User
                             select new User
                             {
                                 Id = CryptHelper.Encrypt(p.Id.ToString()),
                                 UserName = p.sys_UserInfo.UserName
                             }).ToList();

                return Success(query);
            }
        }

        public ActionResult GetUserRole(User user)
        {
            try
            {
                using (CommonDatabase db = new CommonDatabase())
                {
                    int id = CryptHelper.DecryptToInt32(user.Id);
                    string query =
@"select Id, Name, case when RoleId is null then false 
                      else true 
                   end Checked 
from (select * from sys_Role where Id <> 1) t1 
   left join (select RoleId from sys_UserRole where UserId = @user) t2 on t1.Id = t2.RoleId";
                    var dt = db.SetCommand(query, db.Parameter("@user", id))
                               .ExecuteDataTable();
                    return Success(new
                    {
                        Total = dt.Rows.Count,
                        Rows = dt
                    });
                }
            }
            catch (Exception ex)
            {
                return Failed(ex.Message);
            }
        }

        public ActionResult SetUserRole(string user, string roles) 
        {
            try
            {
                int id = CryptHelper.DecryptToInt32(user);
                int[] roleId = JSON.ToObject<int[]>(roles);
                using (CommonDatabase db = new CommonDatabase())
                {
                    db.BeginTransaction();
                    if (db.sys_User.Where(k => k.Id == id && k.State == 1).Count() == 0)
                        throw new ArgumentException("参数错误");

                    db.sys_UserRole.Where(k => k.UserId == id && k.RoleId != 1).Delete();
                    if (roleId != null && roleId.Length > 0) 
                    {
                        var list = new List<sys_UserRole>();
                        foreach (var item in roleId)
                        {
                            list.Add(new sys_UserRole() { UserId = id, RoleId = item });
                        }

                        db.InsertBatch(list);
                    }

                    db.CommitTransaction();
                    return Success();
                }
            }
            catch (Exception ex)
            {
                return Failed(ex.Message);
            }
        }

        public ActionResult Create(User user)
        {
            if (this.ModelState.IsValid)
            {
                try
                {
                    using (CommonDatabase db = new CommonDatabase(CommonOption.ReadWrite))
                    {
                        db.BeginTransaction();

                        if (db.sys_User.Where(k => k.LoginName == user.LoginName && k.State == 1)
                              .Count() > 0)
                        {
                            throw new ArgumentException("用户名不能重复");
                        }

                        string password;
                        string salt;

                        UserAction.EncryptPassword(user.LoginName, user.Password, out password, out salt);
                        
                        int id = Convert.ToInt32(db.sys_User.InsertWithIdentity(() => new sys_User
                        {
                            LoginName = user.LoginName,
                            Password = password,
                            Salt = salt,
                        }));

                        db.sys_UserInfo.Insert(() => new sys_UserInfo 
                        {
                            UserName = user.UserName,
                            Sex = user.Sex,
                            Mobile = user.Mobile,
                            WorkEmail = user.WorkEmail,
                            IDCard = string.Empty,
                            Tel = user.Tel,
                            UserId = id
                        });

                        db.CommitTransaction();
                        return Success();
                    }
                }
                catch (Exception ex)
                {
                    return Failed(ex.Message);
                }
            }

            return ArgumentFailed();
        }

        public ActionResult Update(UpdateUser user)
        {
            if (this.ModelState.IsValid)
            {
                try
                {
                    using (CommonDatabase db = new CommonDatabase(CommonOption.ReadWrite))
                    {
                        db.BeginTransaction();

                        int id = CryptHelper.DecryptToInt32(user.Id);
                        if (db.sys_User.Where(k => k.Id == id && k.LoginName == user.LoginName
                                                              && k.State == 1)
                              .Count() == 0)
                        {
                            throw new ArgumentException("用户不存在");
                        }

                        db.sys_UserInfo
                          .Where(k => k.UserId == id)
                          .Set(k => k.UserName, user.UserName)
                          .Set(k => k.Sex, user.Sex)
                          .Set(k => k.Mobile, user.Mobile)
                          .Set(k => k.WorkEmail, user.WorkEmail)
                          .Set(k => k.Tel, user.Tel)
                          .Update();

                        db.CommitTransaction();
                        return Success();
                    }
                }
                catch (Exception ex)
                {
                    return Failed(ex.Message);
                    //return APIResult.Failed;
                }
            }

            return ArgumentFailed();
        }

        public ActionResult Delete(string Id, string LoginName)
        {
            try
            {
                using (CommonDatabase db = new CommonDatabase(CommonOption.ReadWrite))
                {
                    db.BeginTransaction();

                    int realId = CryptHelper.DecryptToInt32(Id);
                    if (realId == 1)
                    {
                        throw new ArgumentException("无法删除超级管理员账号");
                    }

                    if (db.sys_User.Where(k => k.Id == realId && k.LoginName == LoginName)
                          .Count() == 0)
                    {
                        throw new ArgumentException("用户不存在");
                    }

                    db.sys_User.Where(k => k.Id == realId)
                      .Set(k => k.State, 0)
                      .Update();

                    db.CommitTransaction();
                    return Success();
                }
            }
            catch (Exception ex)
            {
                return Failed(ex.Message);
            }
        }

        public ActionResult ChangePassword(string id, string password)
        {
            if (id.IsNullOrWhiteSpace() ||
                password.IsNullOrWhiteSpace())
                return ArgumentFailed();
            try
            {
                using (CommonDatabase db = new CommonDatabase(CommonOption.ReadWrite))
                {
                    db.BeginTransaction();

                    var realId = CryptHelper.DecryptToInt32(id);
                    var user = db.sys_User.Where(k => k.Id == realId).First();
                    string encrypt;
                    string salt;
                    UserAction.EncryptPassword(user.LoginName, password, out encrypt, out salt);

                    db.sys_User.Where(k => k.Id == realId)
                      .Set(k => k.Password, encrypt)
                      .Set(k => k.Salt, salt)
                      .Set(k => k.UpdatedTime, Sql.GetDate())
                      .Update();

                    db.CommitTransaction();
                    return Success();
                }
            }
            catch (Exception ex)
            {
                return Failed(ex.Message);
            }
        }
    }
}
